package com.qikux.filter;

import cn.hutool.crypto.digest.MD5;
import com.qikux.constraint.RssConst;
import com.qikux.dao.impl.UserDaoImpl;
import com.qikux.entity.User;
import org.haredot.utils.MD5Utils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 记住我过滤器
 */
public class RememberMeFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //1. 如果 没有登录 ，则  从 浏览器中 获取 remember-me 对应的 Cookie 信息
        Object attribute = request.getSession().getAttribute(RssConst.CURRENT_USER);

        // 获取 所有Cookie , 如果没有任何Cookie , 会返回 null
        Cookie[] cookies = request.getCookies();

        if (attribute != null) {
            // 更新 remember-me 时间
            Optional<Cookie> optional = Arrays.stream(cookies)
                    .filter(cookie -> Objects.equals(RssConst.REMEMBER_ME, cookie.getName()))
                    .findFirst();

            Cookie cookie = optional.get();
            // 设置 Cookie 的存活时间，默认为 一周 , 单位秒
            cookie.setMaxAge((int) TimeUnit.DAYS.toSeconds(7));
            cookie.setPath("/");
            response.addCookie(cookie);

            chain.doFilter(request, response);
            return ;
        }


        if (cookies !=null) {
            // 遍历Cookie ，找到 名字 为 remember-me的Cookie
            Optional<Cookie> optional = Arrays.stream(cookies)
                    .filter(cookie -> Objects.equals(RssConst.REMEMBER_ME, cookie.getName()))
                    .findFirst();

            // 如果 没有 找到
            if (optional.isEmpty()) {
                // 继续向下执行
                chain.doFilter(request, response);
                return ;
            }
            Cookie cookie = optional.get();

            //2.  使用 Base64 解码 获取   用户名 +  ”:“  +  UUID  + ":"  +  密文
            String message = new String(Base64.getDecoder().decode(cookie.getValue()), StandardCharsets.UTF_8 ) ;
            // 3. 按照  ":" 进行拆分 ， 获取 三个部分
            String[] dataArray = message.split(":");

            if (dataArray ==null || dataArray.length != 3) {
                throw new RuntimeException("remember-me格式错误");
            }
            //4.  根据 用户名 查询 对应的 存储的  密文 密码
            String username = dataArray[0] ;
            // 借助 持久层对象查询 对应的用户信息
            UserDaoImpl userDao = new UserDaoImpl();
            // 查询用户信息
            User userByTel = userDao.findUserByTel(username);

            //5.  按照   用户名 + ”:“  + UUID + ":"  + key +  密码(密文) 拼接 后 进行 MD5 加密
            MessageFormat messageFormat = new MessageFormat("{0}:{1}:{2}:{3}");
            String text = messageFormat.format(new Object[]{username, dataArray[1], RssConst.KEY, userByTel.getPassword()}) ;
            //6.  获取 加密 后的 数据  和  拆分后的 第三部分内容  进行 比较 ，如果一致 ，说明 密码正确， 则 自动登录。
            if (!Objects.equals(MD5Utils.md5(text), dataArray[2])) {
                //如果 没有任何Cookie ,继续执行
                chain.doFilter(request, response);
                return ;
            }
            // 自动登录
            userByTel.setPassword(null);
            request.getSession().setAttribute(RssConst.CURRENT_USER, userByTel);
        }

        //如果 没有任何Cookie ,继续执行
        chain.doFilter(request, response);
    }
}
